/**
 * @Description: Api请求基础文件
 * @Author: Zander
 * @Date: 2022/11/29 17:46
 * @LastEditors: Zander
 * @LastEditTime: 2022/11/29 17:46
 */
import Request from '@/utils/http';
import { getToken } from '@utils/auth';
import setting from '@/config/setting';
import store from '@/store';
import { isEmpty } from '@utils/verify';
import { commonUtils } from '@utils/common';

const http = new Request({
  timeout: 180 * 1000
});
let logOutMsg = true;

const isPlainRequest = (url) => { return /\.(html?|xml|txt)$/.test(url); }
const useOrigin = (res) => { return res.config?.useOrigin; }

// 拦截请求
http.interceptors.request.use(config => {
  config.baseURL = process.env.VUE_APP_BASE_API;
  config.header = {
    ...Object.assign({
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }, config.header),
    'X-Origin': setting.twOrigin,
    'X-Token': getToken(),
    'X-AppId': setting.appInfo.AppId,
    'X-AppToken': setting.appInfo.AppToken,
    'X-AppSecret': setting.appInfo.AppSecret
  }
  uni.showLoading({
    title: '加载中......'
  })
  return config
}, error => {
  return useOrigin(error) ? Promise.reject(error) : Promise.reject(error.data);
});
// 拦截响应
// eslint-disable-next-line
http.interceptors.response.use(response => {
  const code = response.statusCode;
  uni.hideLoading();
  if ((code >= 200 && code < 300) || code === 304) {
    const resultData = response.data;
    if (!resultData.success) {
      // 令牌失效
      if (resultData.code === 'unauthorized' && logOutMsg) {
        uni.showModal({
          title: '系统提示',
          content: '登录状态已过期，请重新登录!',
          showCancel: false,
          success: res => {
            if (res.confirm) {
              store.dispatch('user/logOut').then(() => {
                uni.reLaunch({
                  url: '/pages/login/login'
                })
              });
            }
          }
        })
        logOutMsg = false;
      }
      // 无权限访问
      if (resultData.code === 'forbidden') {
        uni.reLaunch({
          url: '/pages/login/login'
        })
        commonUtils.toast(resultData.message || '暂无权限', 'warning')
      }
    }
    return isPlainRequest(response.config.url) || useOrigin(response) ? Promise.resolve(response) : Promise.resolve(response.data);
  }
  return Promise.reject(response);
}, error => {
  uni.hideLoading();
  const data = error.data;
  if (data) {
    switch (data.status) {
      case 401:
        if (logOutMsg) {
          uni.showModal({
            title: '系统提示',
            content: '登录状态已过期，请重新登录!',
            showCancel: false,
            success: res => {
              if (res.confirm) {
                store.dispatch('user/logOut').then(() => {
                  uni.reLaunch({
                    url: '/pages/login/login'
                  })
                });
              }
            }
          })
          logOutMsg = false;
        }
        break;
      case 404:
        commonUtils.toast('请求资源不存在', 'error')
        break;
      case 502:
        commonUtils.toast('服务未响应，请稍后再试', 'error')
        break;
      default:
        commonUtils.toast(data.message || '服务未响应，请稍后重试', 'error')
    }
  } else {
    commonUtils.toast(error.message || '服务未响应，请稍后重试', 'error')
  }
  return Promise.reject(error)
})

/**
 * 处理查询参数，排除空值条件
 * @param params
 * @returns {{}}
 */
const getSearchParams = (params) => {
  // 实际参数
  const submitParams = {}
  if (params) {
    for (const key in params) {
      if (Object.prototype.hasOwnProperty.call(params, key)) {
        const value = params[key];
        if (!isEmpty(value)) {
          submitParams[key] = value;
        }
      }
    }
  }
  return submitParams;
}

/**
 * Get请求
 * @param option
 * @returns {Promise<unknown>}
 */
export const $get = (option) => {
  // 实际提交参数
  const submitParams = getSearchParams(option.params);
  Object.assign(option, { method: 'GET', params: submitParams });
  return http.get(option)
};

/**
 * Post请求
 * @param option
 * @returns {Promise<unknown>}
 */
export const $post = (option) => {
  const headers = option.headers;
  if (!headers) {
    Object.assign(option, {
      header: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    });
  }
  Object.assign(option, { method: 'POST', header: headers });
  return http.post(option)
}

/**
 * Put请求
 * @param option
 * @returns {Promise<unknown>}
 */
export const $put = (option) => {
  Object.assign(option, { method: 'PUT' });
  return http.put(option);
}

/**
 * Delete请求
 * @param option
 * @returns {Promise<unknown>}
 */
export const $delete = (option) => {
  Object.assign(option, { method: 'DELETE' });
  return http.delete(option);
}

/**
 * Upload请求
 * @param option
 * @returns {Promise<unknown>}
 */
export const $upload = (option) => {
  Object.assign(option, { method: 'UPLOAD' });
  return http.upload(option);
}

/**
 * Download请求
 * @param option
 * @returns {Promise<unknown>}
 */
export const $download = (option) => {
  Object.assign(option, { method: 'DOWNLOAD' });
  return http.download(option);
}
